home *** CD-ROM | disk | FTP | other *** search
/ Precision Software Appli…tions Silver Collection 1 / Precision Software Applications Silver Collection Volume One (PSM) (1993).iso / demos / devel3.exe / SEGIO.C < prev    next >
C/C++ Source or Header  |  1992-06-05  |  9KB  |  322 lines

  1. /* Segment file i/o */
  2.  
  3. /* Written by Bernie Roehl, March 1992 */
  4.  
  5. /* Copyright 1992 by Bernie Roehl.
  6.    May be freely used to write software for release into the public domain;
  7.    all commercial endeavours MUST contact Bernie Roehl
  8.    for permission to incorporate any part of this software into their
  9.    products!
  10.  */
  11.  
  12. /* The format of a segment file is simple, and very C-like.  Each segment
  13.    is bounded by { and }, and contains any combination of attributes and
  14.    additional segments (which are children of the segment they appear in).
  15.  */
  16.  
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <ctype.h>
  20. #include <string.h>
  21. #include "rend386.h"
  22. #include "plg.h"
  23. #include "segio.h"
  24.  
  25. int readseg_err = 0;
  26.  
  27. #define match(a, b) (!strnicmp((a), (b), strlen(b)))
  28.  
  29. static OBJLIST *curr_objlist = NULL;
  30.  
  31. static char *boundstypes[] = { "NONE", "SPHERE", "BOX", "CSG", NULL };
  32.  
  33. void set_readseg_objlist(OBJLIST *olist)
  34.     {
  35.     curr_objlist = olist;
  36.     }
  37.  
  38. static SEGMENT **seg_array = NULL;
  39. static int seg_array_size = 0;
  40.  
  41. void set_readseg_seglist(SEGMENT **ptr, int maxsegs)
  42.     {
  43.     seg_array = ptr;
  44.     seg_array_size = maxsegs;
  45.     }
  46.  
  47. static unsigned cmap[1000];
  48. static int cmapsize = 0;
  49.  
  50. static process_attribute(char *buff, SEGMENT *seg)
  51.     {
  52.     char filename[100];
  53.     float sx = 1, sy = 1, sz = 1;
  54.     long tx = 0, ty = 0, tz = 0;
  55.     int depth = 0;
  56.     FILE *in;
  57.     cmapsize = 0;
  58.     while (isspace(*buff)) ++buff;
  59.     if (match(buff, "plgfile")) {
  60.         OBJECT *obj;
  61.         char mapfile[100];
  62.         mapfile[0] = '\0';
  63.         sscanf(buff, "plgfile = %s scale %f,%f,%f shift %ld,%ld,%ld sort %d map %s", filename, &sx, &sy, &sz, &tx, &ty, &tz, &depth, mapfile);
  64.         if (mapfile[0]) {
  65.             if ((in = fopen(mapfile, "r")) == NULL) {
  66.                 readseg_err = -1;
  67.                 return -1;
  68.                 }
  69.             for (cmapsize = 0; cmapsize < sizeof(cmap)/sizeof(unsigned) && !feof(in); ++cmapsize) {
  70.                 char buff[100], *p;
  71.                 fgets(buff, sizeof(buff), in);
  72.                 cmap[cmapsize] = (unsigned) strtoul(buff,&p,0); /* req so hex colors usable */
  73.                 }
  74.             fclose(in);
  75.             }
  76.         set_loadplg_scale(sx, sy, sz);
  77.         set_loadplg_offset(tx, ty, tz);
  78.         set_loadplg_depthsort(depth);
  79.         set_loadplg_colormap(cmap, cmapsize);
  80.         seg_set_load_info(seg, filename, sx, sy, sz, tx, ty, tz);
  81.         if ((in = fopen(filename, "r")) == NULL) {
  82.             readseg_err = -1;
  83.             return -1;
  84.             }
  85.         if ((obj = load_plg(in)) == NULL) {
  86.             readseg_err = -2;
  87.             fclose(in);
  88.             return -2;
  89.             }
  90.         seg_setrep(seg, obj);
  91.         set_object_owner(obj, seg);
  92.         if (curr_objlist) add_to_objlist(curr_objlist, obj);
  93.         fclose(in);
  94.         return 0;
  95.         }
  96.     else if (match(buff, "pos")) {
  97.         long tx, ty, tz;
  98.         sscanf(buff, "pos = %ld,%ld,%ld", &tx, &ty, &tz);
  99.         abs_move_segment(seg, tx, ty, tz);
  100.         }
  101.     else if (match(buff, "rot")) {
  102.         float rx, ry, rz;
  103.         sscanf(buff, "rot = %f,%f,%f", &rx, &ry, &rz);
  104.         abs_rot_segment(seg, (long) (rx * 65536L), (long) (ry * 65536L), (long) (rz * 65536L));
  105.         }
  106.     else if (match(buff, "min")) {
  107.         long lims[12];
  108.         char *p;
  109.         if ((p = strchr(buff, '=')) == NULL) return 0;
  110.         do ++p; while (isspace(*p));
  111.         switch (tolower(buff[3])) {
  112.             case 'x':
  113.                 lims[0] = atol(p);
  114.                 set_seg_limits(seg, lims, LIM_MINTX);
  115.                 break;
  116.             case 'y':
  117.                 lims[2] = atol(p);
  118.                 set_seg_limits(seg, lims, LIM_MINTY);
  119.                 break;
  120.             case 'z':
  121.                 lims[4] = atol(p);
  122.                 set_seg_limits(seg, lims, LIM_MINTZ);
  123.                 break;
  124.             case 'r':
  125.                 switch (tolower(buff[4])) {
  126.                     case 'x':
  127.                         lims[6] = atof(p) * 65536L;
  128.                         set_seg_limits(seg, lims, LIM_MINRX);
  129.                         break;
  130.                     case 'y':
  131.                         lims[8] = atof(p) * 65536L;
  132.                         set_seg_limits(seg, lims, LIM_MINRY);
  133.                         break;
  134.                     case 'z':
  135.                         lims[10] = atof(p) * 65536L;
  136.                         set_seg_limits(seg, lims, LIM_MINRZ);
  137.                         break;
  138.                     default: break;
  139.                     }
  140.             default: break;
  141.             }
  142.         }
  143.     else if (match(buff, "max")) {
  144.         long lims[12];
  145.         char *p;
  146.         if ((p = strchr(buff, '=')) == NULL) return 0;
  147.         do ++p; while (isspace(*p));
  148.         switch (tolower(buff[3])) {
  149.             case 'x':
  150.                 lims[1] = atol(p);
  151.                 set_seg_limits(seg, lims, LIM_MAXTX);
  152.                 break;
  153.             case 'y':
  154.                 lims[3] = atol(p);
  155.                 set_seg_limits(seg, lims, LIM_MAXTY);
  156.                 break;
  157.             case 'z':
  158.                 lims[5] = atol(p);
  159.                 set_seg_limits(seg, lims, LIM_MAXTZ);
  160.                 break;
  161.             case 'r':
  162.                 switch (tolower(buff[4])) {
  163.                     case 'x':
  164.                         lims[7] = atof(p) * 65536L;
  165.                         set_seg_limits(seg, lims, LIM_MAXRX);
  166.                         break;
  167.                     case 'y':
  168.                         lims[9] = atof(p) * 65536L;
  169.                         set_seg_limits(seg, lims, LIM_MAXRY);
  170.                         break;
  171.                     case 'z':
  172.                         lims[11] = atof(p) * 65536L;
  173.                         set_seg_limits(seg, lims, LIM_MAXRZ);
  174.                         break;
  175.                     default: break;
  176.                     }
  177.             default: break;
  178.             }
  179.         }
  180.     else if (match(buff, "name")) {
  181.         char *p;
  182.         if ((p = strchr(buff, '=')) == NULL) {
  183.             readseg_err = -3;
  184.             return -3;
  185.             }
  186.         do ++p; while (isspace(*p));
  187.         seg_setname(seg, p);
  188.         }
  189. #ifdef HAVEBOUNDS
  190.     else if (match(buff, "boundstype")) {
  191.         char *p;
  192.         int i;
  193.         if ((p = strchr(buff, '=')) == NULL) {
  194.             readseg_err = -3;
  195.             return -3;
  196.             }
  197.         do ++p; while (isspace(*p));
  198.         for (i = 0; boundstypes[i]; ++i)
  199.             if (match(p, boundstypes[i]))
  200.                 break;
  201.         if (boundstypes[i] == NULL) i = 0;
  202.         set_seg_boundtype(seg, (unsigned char) i);
  203.         }
  204.     else if (match(buff, "boundsorig")) {
  205.         long x = 0, y = 0, z = 0;
  206.         sscanf(buff, "boundsorig = %ld,%ld,%ld", &x, &y, &z);
  207.         set_seg_boundorig(seg, x, y, z);        
  208.         }
  209.     else if (match(buff, "boundslimits")) {
  210.         long x = 0, y = 0, z = 0;
  211.         sscanf(buff, "boundslimits = %ld,%ld,%ld", &x, &y, &z);
  212.         set_seg_boundlimits(seg, x, y, z);        
  213.         }
  214.     else if (match(buff, "hotspot")) {
  215.         long x = 0, y = 0, z = 0;
  216.         sscanf(buff, "hotspot = %ld,%ld,%ld", &x, &y, &z);
  217.         add_hotspot(seg, x, y, z);
  218.         }
  219. #endif
  220.     else if (match(buff, "segnum")) {
  221.         int j;
  222.         sscanf(buff, "segnum = %d", &j);
  223.         if (seg_array && j < seg_array_size) seg_array[j] = seg;        
  224.         }
  225.     /* ignore anything we don't understand */
  226.     return 0;
  227.     }
  228.  
  229. SEGMENT *readseg(FILE *in, SEGMENT *parent)
  230.     {
  231.     SEGMENT *seg;
  232.     char buff[256];
  233.     int c, i = 0;
  234.     if ((seg = new_seg(parent)) == NULL) return NULL;
  235.     while ((c = getc(in)) != EOF) {
  236.         switch (c) {
  237.             case '{':
  238.                 readseg(in, seg);
  239.                 break;
  240.             case '}':
  241.                 return seg;
  242.             case ';':
  243.                 buff[i] = '\0';
  244.                 process_attribute(buff, seg);
  245.                 i = 0;
  246.                 break;
  247.             default:
  248.                 if (i < sizeof(buff)-1) buff[i++] = c;
  249.                 break;
  250.             }
  251.         }
  252.     return seg;
  253.     }
  254.  
  255. static void indent(FILE *out, int level)
  256.     {
  257.     while (level--) fprintf(out, "\t");
  258.     }
  259.     
  260. writeseg(FILE *out, SEGMENT *s, int level)
  261.     {
  262.     SEGMENT *p;
  263.     void *q;
  264.     long tx, ty, tz, rx, ry, rz;
  265.     float frx, fry, frz;
  266.     char *name;
  267.     unsigned char btype;
  268.     unsigned w;
  269.     long lims[12];
  270.     int depth;
  271.     int i;
  272.     indent(out, level);
  273.     fprintf(out, "{\n");
  274.     if ((name = seg_getname(s)) != NULL) {
  275.         indent(out, level);
  276.         fprintf(out, "name = %s;\n", name);
  277.         }
  278.     seg_getposition(s, &tx, &ty, &tz, &rx, &ry, &rz);
  279.     indent(out, level);
  280.     fprintf(out, "pos = %ld,%ld,%ld;\n", tx, ty, tz);
  281.     indent(out, level);
  282.     fprintf(out, "rot = %f,%f,%f;\n", ((float) rx) / 65536L, ((float) ry) / 65536L, ((float) rz) / 65536L);
  283.     w = get_seg_limits(s, lims);
  284.     if (w & LIM_MINTX) { indent(out, level); fprintf(out, "minx = %ld;\n", lims[0]); }
  285.     if (w & LIM_MAXTX) { indent(out, level); fprintf(out, "maxx = %ld;\n", lims[1]); }
  286.     if (w & LIM_MINTY) { indent(out, level); fprintf(out, "miny = %ld;\n", lims[2]); }
  287.     if (w & LIM_MAXTY) { indent(out, level); fprintf(out, "maxy = %ld;\n", lims[3]); }
  288.     if (w & LIM_MINTZ) { indent(out, level); fprintf(out, "minz = %ld;\n", lims[4]); }
  289.     if (w & LIM_MAXTZ) { indent(out, level); fprintf(out, "maxz = %ld;\n", lims[5]); }
  290.     if (w & LIM_MINRX) { indent(out, level); fprintf(out, "minrx = %f;\n", ((float) lims[6])/65536.0); }
  291.     if (w & LIM_MAXRX) { indent(out, level); fprintf(out, "maxrx = %f;\n", ((float) lims[7])/65536.0); }
  292.     if (w & LIM_MINRY) { indent(out, level); fprintf(out, "minry = %f;\n", ((float) lims[8])/65536.0); }
  293.     if (w & LIM_MAXRY) { indent(out, level); fprintf(out, "maxry = %f;\n", ((float) lims[9])/65536.0); }
  294.     if (w & LIM_MINRZ) { indent(out, level); fprintf(out, "minrz = %f;\n", ((float) lims[10]/65536.0)); }
  295.     if (w & LIM_MAXRZ) { indent(out, level); fprintf(out, "maxrz = %f;\n", ((float) lims[11]/65536.0)); }
  296. #ifdef HAVEBOUNDS
  297.     btype = get_seg_boundinfo(s, &tx, &ty, &tz, &rx, &ry, &rz);
  298.     if (btype) {
  299.         indent(out, level);
  300.         fprintf(out, "boundstype = %s;\n", boundstypes[btype]);
  301.         indent(out, level);
  302.         fprintf(out, "boundsorig = %ld,%ld,%ld;\n", tx, ty, tz);
  303.         indent(out, level);
  304.         fprintf(out, "boundslimits = %ld,%ld,%ld;\n", rx, ry, rz);
  305.         }
  306.     for (q = first_hotspot(s, &tx, &ty, &tz); q; q = next_hotspot(q, &tx, &ty, &tz)) {
  307.         indent(out, level);
  308.         fprintf(out, "hotspot = %ld,%ld,%ld;\n", tx, ty, tz);
  309.         }
  310. #endif
  311.     name = seg_get_load_info(s, &frx, &fry, &frz, &tx, &ty, &tz);
  312.     indent(out, level);
  313.     if ((q = seg_getrep(s)) != NULL) depth = get_object_sorting(q);
  314.     else depth = 0;
  315.     fprintf(out, "plgfile = %s scale %f,%f,%f shift %ld,%ld,%ld sort %d;\n", name, frx, fry, frz, tx, ty, tz, depth);
  316.     for (p = child_segment(s); p; p = sibling_segment(p))
  317.         writeseg(out, p, level+1);
  318.     indent(out, level);
  319.     fprintf(out, "}\n");
  320.     return 0;
  321.     }
  322.